#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <linux/fb.h>
#include "Video.h"
#include "Common/Debug.h"

#define NO_MMU

// Variables declare
//Bill modify
unsigned char* _lcd_addr = NULL;	// lcd base address
struct fb_var_screeninfo _fb_var_info;
static int _fb_fd = 0;
static struct fb_fix_screeninfo _fb_fix_info;

char*	Frame_pBits;	// pointer to work buffer
long	Frame_stride;	// stride of work buffer (in bytes)
int		Frame_width;	// width of work buffer (in pixels)
int		Frame_height;	// height of work buffer (not important)

int  dev_VideoInit()
{
	// Init BF533 hardware
	int rc;
///*//////////////////////////////////1225 test 
	if ((_fb_fd = open("/dev/fb0", O_RDWR)) == -1)
	{
		LOG("dev_VideoInit: can't open fixed buffer device!\n");
		return 0;
	}
//*////////////////////////////////////////////////////////
	// lcd_buffer_init
	rc = ioctl(_fb_fd, FBIOGET_FSCREENINFO, &_fb_fix_info);
	if (rc < 0)
	{
		LOG("dev_VideoInit: failed to get fix screen info!\n");
		return 0;
	}


	rc = ioctl(_fb_fd, FBIOGET_VSCREENINFO, &_fb_var_info);
	if (rc < 0)
	{
		LOG("dev_VideoInit: failed to get var screen info!\n");
		return 0;
	}

	_lcd_addr = mmap(0, _fb_fix_info.smem_len, PROT_READ | PROT_WRITE, MAP_FILE | MAP_PRIVATE, _fb_fd, 0);

	if (_lcd_addr == MAP_FAILED)
	{
		LOG("dev_VideoInit: failed to map frame buffer!\n");
		return 0;
	}

	// dump
	LOG("var.xres         = %d\n", _fb_var_info.xres);
	LOG("var.yres         = %d\n", _fb_var_info.yres);
	LOG("var.xres_virtual = %d\n", _fb_var_info.xres_virtual);
	LOG("var.yres_virtual = %d\n", _fb_var_info.yres_virtual);
	LOG("var.xoffset      = %d\n", _fb_var_info.xoffset);
	LOG("var.yoffset      = %d\n", _fb_var_info.yoffset);
	LOG("fix.smem_len	  = %d\n", _fb_fix_info.smem_len);

	dev_VideoSetOffset(0, 0);

	Frame_pBits  = _lcd_addr;
	Frame_width  = _fb_var_info.xres_virtual;
	Frame_height = _fb_var_info.yres_virtual;
#if defined __RGB16
	Frame_stride = Frame_width * 2;
#elif defined __RGB24
	Frame_stride = Frame_width * 3;
#else
	#error	__RGB16 or __RGB24 not defiend!
#endif

	return 1;
}

void dev_VideoDestroy(void)
{
#ifndef NO_MMU
	if (_lcd_addr && _lcd_addr != MAP_FAILED)
		munmap(_lcd_addr, _fb_fix_info.smem_len);
#endif
}

void dev_VideoPresent(void)
{
}

void dev_VideoSetOffset(int x, int y)
{
	int rc;
	
	_fb_var_info.xoffset = x;
	_fb_var_info.yoffset = y;

	rc = ioctl(_fb_fd, FBIOPAN_DISPLAY, &_fb_var_info);

	if (rc < 0)
	{
		LOG("dev_VideoSetOffset: failed invokde ioctl FBIOPAN_DISPLAY!\n");
	}
}

